<?php

namespace app\api\controller;

use app\common\controller\Api;
use EasyWeChat\Factory;
use PhpOffice\PhpSpreadsheet\Helper\Sample;
use Redis;
use think\Db;
use think\Log;
use think\Request;

/**
 * 示例接口
 */
class Goods extends Api
{

    //如果$noNeedLogin为空表示所有接口都需要登录才能请求
    //如果$noNeedRight为空表示所有接口都需要验证权限才能请求
    //如果接口已经设置无需登录,那也就无需鉴权了
    //
    // 无需登录的接口,*表示全部
    protected $noNeedLogin = ['detail','auth','auth_callback','ceshi','pay_callback','orders','handle','teacher'];
    // 无需鉴权的接口,*表示全部
    protected $noNeedRight = ['detail','auth','auth_callback','ceshi','pay_callback','orders','handle','teacher'];

    public function app(){
        $config =  [
            /**
             * 账号基本信息，请从微信公众平台/开放平台获取
             */
            'app_id'  => 'wxc7488634a468bc34',         // AppID
            'secret'  => 'aeb55b60c0133741689c141fe858a43a',     // AppSecret
            'token'   => 'wxc7488634a468bc34Token',          // Token
            'aes_key' => 'vWlZeGta6hY5kCFc97QY3VuO1PxLj56Kx0Dtm4UdZpi',                    // EncodingAESKey，兼容与安全模式下请一定要填写！！！

            /**
             * 指定 API 调用返回结果的类型：array(default)/collection/object/raw/自定义类名
             * 使用自定义类名时，构造函数将会接收一个 `EasyWeChat\Kernel\Http\Response` 实例
             */
            'response_type' => 'array',

            /**
             * 日志配置
             *
             * level: 日志级别, 可选为：
             *         debug/info/notice/warning/error/critical/alert/emergency
             * path：日志文件位置(绝对路径!!!)，要求可写权限
             */
            'log' => [
                'default' => 'dev', // 默认使用的 channel，生产环境可以改为下面的 prod
                'channels' => [
                    // 测试环境
                    'dev' => [
                        'driver' => 'single',
                        'path' => RUNTIME.'/easywechat.log',
                        'level' => 'debug',
                    ],
                    // 生产环境
                    'prod' => [
                        'driver' => 'daily',
                        'path' => RUNTIME.'/easywechat.log',
                        'level' => 'info',
                    ],
                ],
            ],

            /**
             * 接口请求相关配置，超时时间等，具体可用参数请参考：
             * http://docs.guzzlephp.org/en/stable/request-config.html
             *
             * - retries: 重试次数，默认 1，指定当 http 请求失败时重试的次数。
             * - retry_delay: 重试延迟间隔（单位：ms），默认 500
             * - log_template: 指定 HTTP 日志模板，请参考：https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
             */
            'http' => [
                'max_retries' => 1,
                'retry_delay' => 500,
                'timeout' => 5.0,
                // 'base_uri' => 'https://api.weixin.qq.com/', // 如果你在国外想要覆盖默认的 url 的时候才使用，根据不同的模块配置不同的 uri
            ],

            /**
             * OAuth 配置
             *
             * scopes：公众平台（snsapi_userinfo / snsapi_base），开放平台：snsapi_login
             * callback：OAuth授权完成后的回调页地址
             */
            'oauth' => [
                'scopes'   => ['snsapi_userinfo'],
                'callback' => '/index.php/api/goods/auth_callback',
            ],
        ];
         $app = Factory::officialAccount($config);
        return $app;
    }

    public function pay_app(){
        $config = [
            'log' => [
                'default' => 'dev', // 默认使用的 channel，生产环境可以改为下面的 prod
                'channels' => [
                    // 测试环境
                    'dev' => [
                        'driver' => 'single',
                        'path' => RUNTIME.'/easywechat.log',
                        'level' => 'debug',
                    ],
                    // 生产环境
                    'prod' => [
                        'driver' => 'daily',
                        'path' => RUNTIME.'/easywechat.log',
                        'level' => 'info',
                    ],
                ],
            ],
            // 必要配置
            'app_id'             => 'wxc7488634a468bc34',
            'mch_id'             => '1607729773',
            'key'                => 'wxc7488634a468bc34wxc7488634a468',   // API 密钥
            // 如需使用敏感接口（如退款、发送红包等）需要配置 API 证书路径(登录商户平台下载 API 证书)
            'cert_path'          => '../../public/cert/apiclient_cert.pem', // XXX: 绝对路径！！！！
            'key_path'           => '../../public/cert/apiclient_key.pem',      // XXX: 绝对路径！！！！
            'notify_url'         => 'https://'.$_SERVER['SERVER_NAME'].'/index.php/api/goods/pay_callback',     // 你也可以在下单时单独设置来想覆盖它
        ];

        $app = Factory::payment($config);
        return $app;
    }


    /**
     * 商品详情页
     *
     * @ApiTitle    (商品详情页)
     * @ApiSummary  (商品详情页)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/demo/test/id/{id}/name/{name})
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     * @ApiParams   (name="id", type="integer", required=true, description="会员ID")
     * @ApiParams   (name="name", type="string", required=true, description="用户名")
     * @ApiParams   (name="data", type="object", sample="{'user_id':'int','user_name':'string','profile':{'email':'string','age':'integer'}}", description="扩展数据")
     * @ApiReturnParams   (name="code", type="integer", required=true, sample="0")
     * @ApiReturnParams   (name="msg", type="string", required=true, sample="返回成功")
     * @ApiReturnParams   (name="data", type="object", sample="{'user_id':'int','user_name':'string','profile':{'email':'string','age':'integer'}}", description="扩展数据返回")
     * @ApiReturn   ({
         'code':'1',
         'msg':'返回成功'
        })
     */
    public function detail(){
        $sql = "select * from fa_goods";
        $datas = \think\Db::query($sql);
        foreach($datas as $key => $val){
            $goods_image = explode(',',$val['goods_image']);
            $images = [];
            foreach ($goods_image as $image){
                $images[] = 'http://'.$_SERVER['SERVER_NAME'].$image;
            }
            $datas[$key]['goods_image'] = $images;
            $datas[$key]['banner_image'] = 'https://'.$_SERVER['SERVER_NAME'].$val['banner_image'];
            $course = json_decode($val['course'],true);
            $course_new = [];
            foreach ($course as $k =>  $v){
                $course_new[]= [
                    'name' => $k,
                    'link' => $v
                ];
            }
            $openid = $this->request->get('openid');
            $order = \think\Db::table('fa_orders')->where("openid = '$openid' and status = 1")->select();
            if(!empty($order)){
                $datas[$key]['pay_status'] = 1;
            }else{
                $datas[$key]['pay_status'] = 0;
            }
            $datas[$key]['course'] = $course_new;
        }
        $this->success('',$datas);
    }


    public function redis(){
        //连接本地的 Redis 服务
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        return $redis;

    }

    public function auth(){
        $channel_id = $this->request->get('channel_id');
        $app = $this->app();
        $oauth = $app->oauth;
//        if (empty(\think\Session::get('wechat_user'))) {
//        return  $oauth->redirect('https://'.$_SERVER['SERVER_NAME'].'/index.php/api/goods/auth_callback?channel_id='.$channel_id);
//        }
        $oauth->redirect('https://'.$_SERVER['SERVER_NAME'].'/index.php/api/goods/auth_callback?channel_id='.$channel_id)->send();
//        $targetUrl = '/index.html';
//        header('location:'. $redirectUrl);
    }

    public function auth_callback(){
        // 获取 OAuth 授权结果用户信息
        $channel_id = $this->request->get('channel_id');
        $app = $this->app();
        $oauth = $app->oauth;
        $user = $oauth->user()->toArray();
        $arrs = $user['original'];
        $arrs['channel_id'] = $channel_id;
        unset($arrs['privilege']);
        $arrs['createtime'] = time();
        $result =\think\Db::query("select * from fa_wechat_user where openid = '{$arrs['openid']}'");
        if(!$result){
            \think\Db::table('fa_wechat_user')->insert($arrs);
        }
        \think\Session::set('wechat_user',$user);
        $targetUrl = '/index.html#/?openid='.$arrs['openid'].'&channel_id='.$channel_id;
        header('location:'. $targetUrl); // 跳转到 user/profile
    }

    public function ceshi(){
        $message['out_trade_no'] = 'D_1617367734606712b6ec88e';
        $order['goods_id'] = '3';
        \think\Db::execute("UPDATE `fa_orders` SET `status` = '1' WHERE out_trade_no = '{$message['out_trade_no']}'");
        \think\Db::execute("UPDATE `fa_goods` SET num = num-1 WHERE `id` = '{$order['goods_id']}'");
        $rate = \think\Db::query("select * from fa_config_value where `key` = 'teacher_rate'")[0];
        $rate_value = intval($rate['value']);
        $teacher = \think\Db::query("SELECT id as teacher_id FROM fa_teachers");
        foreach ($teacher as $k => $v){
            $teacher[$k]['count'] = \think\Db::query("SELECT count(1) as count  FROM fa_wechat_user where teacher_id = '{$v['teacher_id']}'")[0]['count'];
        }
        $rate_value = 2;
        $teacher_id = $teacher[0]['teacher_id'];
        if($rate_value == 1){
            foreach ($teacher as $k => $v){
               if($k >= 1){
                   if($teacher[$k]['count'] < $teacher[$k-1]['count']){
                       $teacher_id = $v['teacher_id'];
                   }

               }
            }
        }else{
            for ($i=1;$i<=count($teacher)-1;$i++){
                $new = $teacher[$i]['count'];
                $last = $teacher[$i-1]['count'];
                if(($last-$new) == $rate_value || $new%$rate_value !=0){
                    $teacher_id = $teacher[$i]['teacher_id'];
                }
            }

        }
        var_dump($teacher_id);
//        foreach ($teacher as $k => $v){
//            $count = \think\Db::table('fa_wechat_user')->where("teacher_id = '{$v['id']}'")->count();
//            if($count > $rate_value){
//                continue;
//            }else{
//                \think\Db::execute("UPDATE `fa_wechat_user` SET `teacher_id` = '{$v['id']}' WHERE `openid` = '{$order['openid']}'");
//            }
//        }
    }

    public function handle(){
        $openid = $this->request->get('openid');
        $teacher_id = $this->request->get('teacher_id');
        $channel_id = $this->request->get('channel_id');
        $result =\think\Db::query("select * from fa_teachers_openid where openid = '$openid'");
        if(!$result){
            \think\Db::table('fa_teachers_openid')->insert(['openid' =>$openid,'teacher_id' =>$teacher_id,'channel_id' => $channel_id]);
        }
        $this->success('',$result);
    }

    public function teacher(){
        $openid = $this->request->get('openid');
        $sql = "select t.* from fa_wechat_user u left join fa_teachers t on u.teacher_id = t.id where u.openid = '$openid'";
        $teacher = \think\Db::query($sql)[0];
        $teacher['image'] = 'http://'.$_SERVER['SERVER_NAME'].$teacher['image'];
        $this->success($teacher);
    }

    /**
     * 支付回调
     */
    public function pay_callback(){
        $app = $this->pay_app();
        $response = $app->handlePaidNotify(function($message, $fail){
            file_put_contents(RUNTIME.'pay_callback',json_encode($message,JSON_UNESCAPED_UNICODE));
//            // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
            $order = \think\Db::table('fa_orders')->where("out_trade_no = '{$message['out_trade_no']}'")->select()[0];
            if ($order['status'] == 1) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
//
            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                // 用户是否支付成功
                    if ($message['result_code'] === 'SUCCESS') {
                        \think\Db::execute("UPDATE `fa_orders` SET `status` = '1' WHERE out_trade_no = '{$message['out_trade_no']}'");
//                        \think\Db::execute("UPDATE `fa_goods` SET num = num-1 WHERE `id` = '{$order['goods_id']}'");
                        $rate = \think\Db::query("select * from fa_config_value where `key` = 'teacher_rate'")[0];
                        $rate_value = intval($rate['value']);
                        $teacher = \think\Db::query("SELECT id as teacher_id FROM fa_teachers");
                        foreach ($teacher as $k => $v){
                            $teacher[$k]['count'] = \think\Db::query("SELECT count(1) as count  FROM fa_wechat_user where teacher_id = '{$v['teacher_id']}'")[0]['count'];
                        }
                        $teacher_id = $teacher[0]['teacher_id'];
                        if($rate_value == 1){
                            foreach ($teacher as $k => $v){
                                if($k >= 1){
                                    if($teacher[$k]['count'] < $teacher[$k-1]['count']){
                                        $teacher_id = $v['teacher_id'];
                                    }

                                }
                            }
                        }else{
                            for ($i=1;$i<=count($teacher)-1;$i++){
                                $new = $teacher[$i]['count'];
                                $last = $teacher[$i-1]['count'];
                                if(($last-$new) == $rate_value || $new%$rate_value !=0){
                                    $teacher_id = $teacher[$i]['teacher_id'];
                                }
                            }

                        }
                        \think\Db::execute("UPDATE `fa_wechat_user` SET `teacher_id` = '{$teacher_id}' WHERE `openid` = '{$order['openid']}'");


                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }

            $order->save(); // 保存订单

            return true; // 返回处理完成
        });

        $response->send(); // return $response;
    }

    public function orders()
    {
        $app = $this->pay_app();
        $openid = $this->request->get('openid');
        $goods_name = $this->request->get('goods_name');
        $money = $this->request->get('money');
        $money = $money*100;
        $goods_id = $this->request->get('goods_id');
        $channel_id = $this->request->get('channel_id');
        $out_trade_no = 'D_' . time() . uniqid();
        $result = $app->order->unify([
            'body' => $goods_name,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $money,
            'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], // 可选，如不传该参数，SDK 将会自动获取相应 IP 地址
            'notify_url' => 'https://' . $_SERVER['SERVER_NAME'] . '/index.php/api/goods/pay_callback', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $openid,
        ]);
        if ($result['return_code'] == 'SUCCESS') {
            $arrs = [
                'out_trade_no' => $out_trade_no,
                'goods_id' => $goods_id,
                'goods_name' => $goods_name,
                'openid' => $openid,
                'total_fee' => $money,
                'status' => 0,
                'prepay_id' => $result['prepay_id'],
                'result' => json_encode($result, JSON_UNESCAPED_UNICODE),
                'channel_id' => $channel_id,
                'created_at' => date('Y-m-d H:i:s')
            ];
            \think\Db::table("fa_orders")->insert($arrs);
        }
        $jssdk = $app->jssdk;
        $config = $jssdk->sdkConfig($result['prepay_id']);
        $this->success('', $config);
    }

}
